
package net.vinote.smart.platform.module.database;

import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.vinote.smart.platform.base.Platform;
import net.vinote.smart.platform.comm.PlatformConst;
import net.vinote.smart.platform.exception.SerialNoException;
import net.vinote.smart.platform.module.database.bo.BizObject;
import net.vinote.smart.platform.module.database.bo.DBQuery;


/**
 * 
 * 主键自动生成策略
 * 
 * @author 郑俊伟
 * 
 */
public class DefaultPrimaryKeyStrategy implements PrimaryKeyGenerateStrategy
{
	private Map<String, SerialNo> serialMap = new HashMap<String, SerialNo>();;

	private String tableName;

	DecimalFormat format = new DecimalFormat("00");

	@Override
	public void setBizObject(BizObject bo)
	{

	}

	@Override
	public void setTableName(String tableName)
	{
		this.tableName = tableName;
	}

	@Override
	public String getSerialNo()
	{

		SerialNo serialNo = serialMap.get(tableName);
		SimpleDateFormat sdf = new SimpleDateFormat(
				PlatformConst.DateFormat.DATE);
		String dateStr = sdf.format(new Date());
		if (serialNo == null)
		{
			synchronized (SerialNoManager.class)
			{
				serialNo = serialMap.get(tableName);
				if (serialNo == null)
				{
					serialNo = new SerialNo();
					Table tab = Platform.getAttribute(
							PlatformConst.SRE_PREFIX_TABLE + tableName,
							Table.class);
					if (tab == null)
					{
						throw new SerialNoException("Table " + tableName
								+ " is not exists!");
					}
					List<Field> keyList = tab.getKey();
					if (keyList.size() != PlatformConst.Number.ONE)
					{
						throw new SerialNoException(
								"primary key number is not one!");
					}
					// 获取当前表的最新serialNo
					DBManager bm = new DBManager(tableName);
					try
					{
						String key = keyList.get(0).getFieldName();
						DBQuery query = bm.createQuery(new String[]
						{
							key
						}, key + " like ? order by " + key + " desc")
								.setParamVal(dateStr + "%");
						query.setPagination(1, 1);// 提高性能
						BizObject bo = query.getSingleResult();
						serialNo.date = dateStr;
						if (bo == null)
						{
							serialNo.serialNo = 0;
						}
						else
						{
							serialNo.serialNo = format.parse(
									bo.getAttribute(key).substring(
											PlatformConst.DateFormat.DATE
													.length())).intValue();
						}
						serialMap.put(tableName, serialNo);
					}
					catch (SQLException e)
					{
						e.printStackTrace();
					}
					catch (ParseException e)
					{
						e.printStackTrace();
					}
				}
			}

		}
		synchronized (serialMap.get(tableName))
		{
			if (!dateStr.equals(serialNo.date))
			{
				serialNo.date = dateStr;
				serialNo.serialNo = 0;
			}
			return serialNo.date + format.format(++serialNo.serialNo);
		}

	}

	private class SerialNo
	{
		private String date;

		private int serialNo;
	}
}
